home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
powern.arc
/
POWERN.INC
Wrap
Text File
|
1985-07-22
|
2KB
|
64 lines
{ POWERN.PLB #1.04 85-06-22 FAST INTEGER POWERS OF REAL NUMBERS
V01 L04 pretty-print update on 85-06-22 with expanded remarks by DEH
L03 update on 85-06-18 by DEH to expand on an unpublished idea
of David Gries.
L02 update on 85-06-11 by DEH for draft DDJ pretty printing.
L01 update on 85-06-09 by DEH to smooth out some rough edges.
L00 created on 85-06-05 by Dennis E. Hamilton in order to answer
a number of electronic requests for help with Pascal powers.}
function
PowerN(x: real; {initial value: x0}
n: integer {required exponent} )
:real {value of x0^n or x0**n};
var i: integer {non-negative power of x which remains to be computed};
r: real {running intermediate-result value};
procedure
MakeOdd;
begin {V01 L03 Knuth transformation re-ordered to exploit
initial i > 0 and even, thanks to the Gries adjustment.}
repeat {reduction of i while preserving x0^abs(n) = r*x^i}
x := sqr(x);
i := i shr 1;
{or use i := i div 2 when shifting is not supported}
until odd(i);
end; {transformation of x^(2*k) to sqr(x)^k until odd k reached}
BEGIN {PowerN}
if n = 0
then begin
if abs(x) = 0.0
{V01 L01: Insulating against Turbo Pascal and
IEEE -0.0 possibilities}
then PowerN := x/x
{In the indeterminate 0^0 case, defer to the system's
treatment of 0/0 for appropriate continuation.}
else PowerN := 1.0;
end
else begin {n <> 0 now guaranteed}
i := abs(n);
if not odd(i) then MakeOdd;
{V01 L03 odd(i) now guaranteed}
r := x; i := pred(i);
{V01 L03 even(i) now guaranteed for the Gries invariant}
while i <> 0
do begin {not odd(i) and x0^abs(n) = r*x^i}
MakeOdd;
r := r*x; i := pred(i);
end {Gries-invariant version of the Knuth transformation
as re-expressed in Dijkstra-Jensen-Wirth form};
if n < 0
then PowerN := 1.0/r
else PowerN := r;
end;
END {PowerN};